home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / gnustuff / minix / update~4.z / update~4 / lib_stdio_stdiolib.h < prev    next >
Encoding:
C/C++ Source or Header  |  1989-09-06  |  6.7 KB  |  231 lines

  1. /*            s t d i o l i b
  2.  *
  3.  * (C) Copyright C E Chew
  4.  *
  5.  * Feel free to copy, use and distribute this software provided:
  6.  *
  7.  *    1. you do not pretend that you wrote it
  8.  *    2. you leave this copyright notice intact.
  9.  *
  10.  * This include file is used by the stdio code. It provides some
  11.  * useful macro definitions that make the code a bit easier to
  12.  * write.
  13.  *
  14.  * Patchlevel 1.2
  15.  *
  16.  * Edit History:
  17.  * 06-Sep-1989    Cast first argument of _flsbuf().
  18.  * 05-Sep-1989    Remove dependency on MINIX define. Define P() instead
  19.  *        of Prototype() (apparently less distracting). Use
  20.  *        atexit() instead of __cleanup for better portability.
  21.  *        For ld type loaders, we can use a loader trick
  22.  *        and not use an explicit call to atexit thus SETIOFLUSH
  23.  *        can be empty (almost).
  24.  * 03-Sep-1989    Added BUFFERSIZE() and altered UNUSEDINBUFFER() to
  25.  *        accommodate line buffered streams. Added PUTC()
  26.  *        and NPUTC() for non line buffered streams.
  27.  */
  28.  
  29. #include <stdio.h>
  30. #include <varargs.h>
  31. #include <errno.h>
  32.  
  33. #if    defined(__STDC__)
  34. #  if    !defined(__NO_PROTO__)
  35. #    define    P(x)    x
  36. #  else
  37. #    define    P(x)    ()
  38. #  endif
  39. #else
  40. # define    P(x)    ()
  41. #endif
  42.  
  43. void _ioflush    P((void));        /* flush output */
  44. void _ioexit    P((void));        /* exit linking function */
  45. int _allocbuf    P((FILE *));        /* internal buffering */
  46. int _fopen    P((CONST char *, CONST char *, int, short *)); /* fopen assist */
  47. FILE **_slot    P((FILE *));        /* find a slot */
  48. FILE *_file    P((FILE *, int, short)); /* initialise FILE */
  49.  
  50. int atexit    P((void (*)(void)));    /* specify wrapup */
  51.  
  52. extern int _wrapstdio;            /* stdio wrap required */
  53. extern int errno;            /* system error number */
  54.  
  55. /* Flag manipulation macros */
  56.  
  57. #define TESTFLAG(f,x)    (((f)->_flag & (x)) != 0)
  58. #define SETFLAG(f,x)    ((f)->_flag |= (x))
  59. #define CLEARFLAG(f,x)    ((f)->_flag &= ~(x))
  60. #define GETFLAG(f,x)    ((f)->_flag & (x))
  61. #define TOGGLEFLAG(f,x)    ((f)->_flag ^= (x))
  62.  
  63. /* Add _ioflush to exit code
  64.  *
  65.  * Check is _ioflush needs to be added to the exit code. If so then
  66.  * add it. This macro is run time system dependent.
  67.  */
  68. #if    defined(MSDOS)
  69. # define SETIOFLUSH() { if (_wrapstdio != 0) _wrapstdio = atexit(_ioflush); }
  70. #endif
  71.  
  72. #if    !defined(SETIOFLUSH)
  73. # define SETIOFLUSH() _ioexit()
  74. #endif
  75.  
  76. /* Putc for non buffered streams
  77.  *
  78.  * This version of putc is explicitly for unbuffered streams. A
  79.  * call is made directly to the buffer flushing code.
  80.  */
  81. #define NPUTC(x,p) ( _flsbuf((unsigned char)(x),(p)) )
  82.  
  83.  
  84. /* Putc without line buffering
  85.  *
  86.  * This version of putc() should be exactly the same as that declared
  87.  * in stdio.h except that it shouldn't worry about line buffering.
  88.  */
  89. #define PUTC(x,p) ( \
  90.   (p)->_ptr < (p)->_base + (p)->_bufsiz \
  91.   ? (int) (*(p)->_ptr++ = (unsigned char)(x)) \
  92.   : _flsbuf((unsigned char)(x),(p)) \
  93. )
  94.  
  95. /* Initialise an output buffer
  96.  *
  97.  * This macro uses _base and _bufsiz to initialise _ptr and _end. _ptr
  98.  * will be set to point at the base of the buffer. _end will be set
  99.  * to point at one past the end of the buffer if the stream is buffered
  100.  * otherwise it will point at the base of the buffer. Line buffered
  101.  * streams are considered to be fully buffered.
  102.  */
  103. #define INITWRITEBUFFER(f) ( \
  104.   (f)->_end = ((f)->_ptr = (f)->_base) + \
  105.               (TESTFLAG(f, _IONBF | _IOLBF) ? 0 : (f)->_bufsiz) \
  106. )
  107.  
  108. /* Initialise a buffer to call either _flsbuf or _filbuf
  109.  *
  110.  * This macro initialises the buffer by setting _end and _ptr to
  111.  * _base. This will force the next putc or getc to call the
  112.  * appropriate routine. This is used by the r+, w+ and a+ modes
  113.  * of access.
  114.  */
  115. #define FLUSHNEXTACCESS(f) ( \
  116.   (f)->_end = (f)->_ptr = (f)->_base \
  117. )
  118.  
  119. /* Initialise an output buffer to call _flsbuf
  120.  *
  121.  * This macro initialises the output buffer setting _ptr to _base.
  122.  * _end is set to be _base so that _flsbuf will be called on the
  123.  * next putc.
  124.  */
  125. #define FLUSHNEXTWRITE(f) ( \
  126.   (f)->_end = (f)->_ptr = (f)->_base \
  127. )
  128.  
  129. /* Initialise an input buffer
  130.  *
  131.  * This macro empties an input buffer. It uses _base to initialise
  132.  * _ptr and sets _end to point to the high water mark of the buffer.
  133.  *
  134.  * If the argument v is zero, this macro must have the same effect
  135.  * as a call to FLUSHNEXTACCESS(f).
  136.  */
  137. #define INITREADBUFFER(f, v) ( \
  138.   (f)->_end = ((f)->_ptr = (f)->_base) + (v) \
  139. )
  140.  
  141. /* Initialise a buffer
  142.  *
  143.  * This macro will empty a buffer. It will decide whether it is
  144.  * an input or output buffer by examining _IOWRITE. In the case
  145.  * of a read, _ptr is set so that _filbuf will be called when
  146.  * the stream is next read. In the case of a write, the
  147.  * buffer is initialised so that it can be used for writing.
  148.  *
  149.  * Note that streams opened for update will be set as if they
  150.  * were opened for reading.
  151.  */
  152. #define INITBUFFER(f) ( \
  153.   TESTFLAG((f), _IOWRITE) ? INITWRITEBUFFER((f)) \
  154.               : INITREADBUFFER((f), 0) \
  155. )
  156.  
  157. /* Buffer size
  158.  *
  159.  * Return the size of the output buffer. This will return rubbish
  160.  * for unbuffered streams. Line and fully buffered streams will
  161.  * have the true buffer size returned.
  162.  */
  163. #define BUFFERSIZE(f) ( (f)->_bufsiz )
  164.  
  165. /* Bytes left in input buffer
  166.  *
  167.  * This macro returns the number of bytes left in an input buffer.
  168.  */
  169. #define BYTESINREADBUFFER(f) ( (f)->_end - (f)->_ptr )
  170.  
  171. /* Bytes written in output buffer
  172.  *
  173.  * This macro returns the number of bytes left in an output buffer.
  174.  */
  175. #define BYTESINWRITEBUFFER(f) ( (f)->_ptr - (f)->_base )
  176.  
  177. /* Unused bytes in output buffer
  178.  *
  179.  * This macro returns the number of unused bytes in an output buffer.
  180.  * Unbuffered streams will return rubbish. Line and fully buffered streams
  181.  * will have the amount of space remaining returned.
  182.  */
  183. #define UNUSEDINWRITEBUFFER(f) ( (f)->_bufsiz - ((f)->_ptr - (f)->_base) )
  184.  
  185. /* Get pointer into write buffer
  186.  *
  187.  * This macro gets the pointer into the write buffer.
  188.  */
  189. #define GETWRITEPTR(f) ( (f)->_ptr )
  190.  
  191. /* Set pointer into write buffer
  192.  *
  193.  * This macro sets the pointer into the write buffer.
  194.  */
  195. #define SETWRITEPTR(f,p) ( (f)->_ptr = (p) )
  196.  
  197. /* Get pointer into read buffer
  198.  *
  199.  * This macro gets the pointer into the read buffer.
  200.  */
  201. #define GETREADPTR(f) ( (f)->_ptr )
  202.  
  203. /* Set pointer into read buffer
  204.  *
  205.  * This macro sets the pointer into the read buffer.
  206.  */
  207. #define SETREADPTR(f,p) ( (f)->_ptr = (p) )
  208.  
  209. /* Check if buffering has been set
  210.  *
  211.  * Return true if buffering has already been set. A stream
  212.  * set for unbuffered output is considered to have had
  213.  * its buffering set.
  214.  */
  215. #define HASBUFFER(f) ( (f)->_base != 0 )
  216.  
  217. /* Unroll a loop
  218.  *
  219.  * Assume that the loop must execute at least once. The first argument
  220.  * is the name of the loop control variable. The second argument is
  221.  * the expression to be placed in the loop body. The control variable
  222.  * should be unsigned, otherwise the right shift might propagate the sign
  223.  * bit. The caller must also provide the name of a unique label.
  224.  */
  225. # define UNROLL_DO(l,v,x) { \
  226.   char t = (v); \
  227.   (v) = ((v)+1) >> 1; \
  228.   if (t & 1) goto l; \
  229.   do { x; l: x; } while (--(v)); \
  230. }
  231.